import { app, shell, BrowserWindow,session,dialog,ipcMain } from 'electron'
import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.png?asset'

const { promisify } = require('util');
const fs = require('fs');
const readFile = promisify(fs.readFile);
const FormData = require('form-data');
const axios = require('axios'); // 用于发送 HTTP 请求的库
const os = require('os');

const { execFile } = require('child_process'); // 用于执行命令行命令

const low = require('lowdb');
const FileSync = require('lowdb/adapters/FileSync');
// const adapter = new FileSync(join(__dirname, 'database.db'));
const adapter = new FileSync('database.db');
const db = low(adapter);
db.defaults({local_table: []}).write();
  



var mainWindow;

function createWindow(): void {
	// Create the browser window.

	mainWindow = new BrowserWindow({
		width: 1000,
		height: 670,
		show: false,
		autoHideMenuBar: true,
		// ...(process.platform === 'linux' ? { icon } : {}),
		icon:icon, //图标
		webPreferences: {
			preload: join(__dirname, '../preload/index.js'),
			sandbox: false,
            webSecurity: false, //关闭安全检查， 允许跨域， 不推荐
			webviewTag:true,
            nodeIntegration: true,
			contextIsolation:false,
		}
	})

	mainWindow.on('ready-to-show', () => {
		mainWindow.show()
	})

	mainWindow.webContents.setWindowOpenHandler((details) => {
		shell.openExternal(details.url)
		return { action: 'deny' }
	})

	// HMR for renderer base on electron-vite cli.
	// Load the remote URL for development or the local html file for production.
	if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
		mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
		// if (!process.env.IS_TEST) childWindow.webContents.openDevTools(); // 打开调试工具
	} else {
		mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
	}

	mainWindow.webContents.openDevTools({ mode: 'right' });

	const filter = { urls: ['*://*/*'] }
	session.defaultSession.webRequest.onBeforeSendHeaders(filter, (details, callback) => {
		details.requestHeaders['Origin'] = '*'
		callback({ cancel: false, requestHeaders: details.requestHeaders })
	})

}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
	// Set app user model id for windows
	electronApp.setAppUserModelId('com.electron')

	// Default open or close DevTools by F12 in development
	// and ignore CommandOrControl + R in production.
	// see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
	app.on('browser-window-created', (_, window) => {
		optimizer.watchWindowShortcuts(window)
	})

	createWindow()

	app.on('activate', function () {
		// On macOS it's common to re-create a window in the app when the
		// dock icon is clicked and there are no other windows open.
		if (BrowserWindow.getAllWindows().length === 0) createWindow()
	})
/* 
	//禁用F5刷新
    globalShortcut.register('f5', () => {
		console.log('F5 is pressed but refresh is disabled');
        // 不执行mainWindow.reload()
    });
	//禁用快捷键control+r刷新
    globalShortcut.register('CommandOrControl+R', () => {
        console.log('CommandOrControl+R is pressed but refresh is disabled');
        // 不执行mainWindow.reload()
    });
 */
})

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
	if (process.platform !== 'darwin') {
		app.quit()
	}
})


// In this file you can include the rest of your app"s specific main process
// code. You can also put them in separate files and require them here.


//监听打开导入弹窗
ipcMain.on("open-import-project-window", async function (_event, opts) {
	const { title='选择项目' } = opts;
	const result = await dialog.showOpenDialog(mainWindow, {
		title : title,
		properties: ['openDirectory']
	});
	mainWindow.webContents.send("get-import-project-info", JSON.stringify(result));
});

// 设置窗口标题
ipcMain.on("set-title", async function (_event, title) {
	mainWindow.setTitle(title);
});

// 监听 'upload-file' 上传提交小程序源码
ipcMain.on('upload-file', async (_event,item) => {
	try {
		// 读取文件内容(设置编码后文件就报错)
		const fileContent = await readFile(item.filePath);

		// 构造 FormData 对象以发送文件
		const formData = new FormData();
		formData.append('file', fileContent, item.fileName);
		formData.append('appId', item.appId);
		formData.append('windowWidth', item.windowWidth);
		formData.append('windowHeight', item.windowHeight);
		formData.append('entryPath', item.entryPath);

		console.log('上传源码中');
		var str=new Date().getTime();
		// 发送 HTTP POST 请求到服务器进行上传
		let result=await axios.post(item.url, formData, {
			headers: { 'Content-Type': 'multipart/form-data;boundary='+str }
			// headers: { 'Content-Type': 'application/octet-stream' }
		});
		console.log('File uploaded successfully',result.data);
		mainWindow.webContents.send("upload-file-done");
	} catch (error) {
		console.error('Error uploading file:', error);
		mainWindow.webContents.send("upload-file-err",error);
	}
});


//创建项目
ipcMain.on("create-project",(_event, opts)=> {
	
	const params=JSON.parse(opts);
	// 获取当前用户的主目录
	const userHomeDir = os.homedir();
	//项目路径
	const projectPath=userHomeDir+'/RaymondAppProject/'+params.nameProject;
	// 同步检查文件夹是否存在
	if(fs.existsSync(projectPath)) {
		// console.log('文件夹存在');
		mainWindow.webContents.send("create-project-success","");
		return;
	}

	//创建项目
	fs.mkdirSync(projectPath,{recursive:true});
	const files = [
		{name:'project.config.json',content:`
{
	"projectname": "${params.appId}",
  	"description": "",
	"appid": "${params.appId}",
	"setting":"",
	"windowWidth": 400,
	"windowHeight": 600
}
		`},
		{name:'app.js',content:`
// app.js
App({
	onLaunch() {
		console.log('app.js onLaunch');
	},
	onShow() {
		console.log('app.js onShow');
	},
	onHide() {
		console.log('app.js onHide');
	},
})
		`},
		{name:'app.wxss',content:''},
		{name:'app.json',content:`
{
	"pages":[
		"pages/index/index"
	],
	"window":{
		"navigationBarTextStyle": "black",
		"navigationBarTitleText": "raymond app",
		"navigationBarBackgroundColor": "#ffffff"
	}
}
		`},
	];
	files.forEach(file => {
		fs.writeFileSync(projectPath+'/'+file.name, file.content);
	});
	const folders = [
		{name:'pages',subfolder:{
				name:'index',
				file:[
					{name:'index.js',content:`
Page({
	data: {
		text:"hello world",
	},
	onLoad: function (options) {
		console.log('onLoad');
	},
	onShow: function () {
		console.log('onShow');
	},
	onReady: function () {
		console.log('onReady');
	},
	onHide: function () {
		console.log('onHide');
	},
	onUnload: function () {
		console.log('onUnload');
	},
	onPageScroll: function (opts) {
		console.log('onPageScroll');
	},
});
						`},
					{name:'index.json',content:`
{
	"navigationBarTextStyle": "white",
	"backgroundColor": "#000",
	"usingComponents": {}
}
						`},
					{name:'index.wxml',content:`
<view class="container">{{text}}</view>
						`},
					{name:'index.wxss',content:''},
				]
			}
		},
		{name:'utils',file:'index.js'}
	];
	folders.forEach(folder => {
		let newProjectPath=`${projectPath}/${folder.name}/`;
		if(folder.subfolder){
			fs.mkdirSync(newProjectPath+folder.subfolder.name,{recursive:true});
			folder.subfolder.file.forEach(file => {
				fs.writeFileSync(newProjectPath+folder.subfolder.name+'/'+file.name, file.content);
			});
		}else{
			fs.mkdirSync(projectPath+'/'+folder.name,{recursive:true});
			fs.writeFileSync(newProjectPath+folder.file, '');
		}
	});

	mainWindow.webContents.send("create-project-success",projectPath);
});


//监听调用系统api模块消息
ipcMain.on("message-sys-api", (_event, opts)=> {
    const {messageId,type, data} = opts;
	let result='';
	switch (type) {
		case "writeFileSync":
			//写入文件
			result=fs.writeFileSync(data.file, data.content, 'utf-8');
			break;
		case "readFileSync":
			//读取文件
			result=fs.readFileSync(data.file, 'utf-8');
			break;
		case "existsSync":
			//检查文件,文件夹是否存在
			result=fs.existsSync(data.file)
			break;
		case "homeDir":
			// 获取当前用户的主目录
			const userHomeDir = os.homedir();
			result=userHomeDir;
			break;
		default:
	}
	mainWindow.webContents.send("on-message-sys-api",{messageId,result});
});


ipcMain.on('read-config-file', (_event,opts) => {
	let result=fs.readFileSync(opts.currProjectPath+'/compileResult.json', 'utf-8')
	mainWindow.webContents.send('config-info', result);
});

//打开资源管理器
ipcMain.on('open-explorer', (_event,opts) => {
	const { exec } = require('child_process');
	exec(`explorer "${opts.projectPath}"`, (error, stdout, stderr) => {
		if (error) {
			console.error(`exec error: ${error}`);
			return;
		}
		console.log(`stdout: ${stdout}`);
		console.error(`stderr: ${stderr}`);
	});
});


//监听调用系统api模块消息
ipcMain.on("sys-api-message", async (_event, opts)=> {
	// console.log("sys-api-message:",opts)
	const {messageId,type, data} = opts;
	let result:any='';
	switch (type) {
		case "writeFileSync":
			//写入文件
			result=fs.writeFileSync(data.file, data.content, 'utf-8');
			break;
		case "readFileSync":
			//读取文件
			result=fs.readFileSync(data.file, 'utf-8');
			break;
		case "existsSync":
			//检查文件,文件夹是否存在
			result=fs.existsSync(data.file)
			break;
		case "homeDir":
			// 获取当前用户的主目录
			const userHomeDir = os.homedir();
			result=userHomeDir;
			break;
		case "setStorage":
			// 查询单条数据
			let localTableData=db.get('local_table').find({ key: data.key }).value();
			if(!localTableData){
				// 插入单条数据
				db.get('local_table').push({ key: data.key, value: data.value }).write();
			}else{
				// 更新单条数据
				db.get('local_table').find({ key: data.key }).assign({ value: data.value }).write();
			}
			break;
		case "getStorage":
			// 查询单条数据
			let localData=db.get('local_table').find({ key: data.key }).value();
			result=localData?localData.value:'';
			break;
		case "removeStorage":
			// 删除单条数据
			db.get('local_table').remove({ key: data.key }).write();
			break;
		case "clearStorage":
			// 删除表中所有数据
			db.get('local_table').remove().write();
			break;
		case "openDialog":
			result = await dialog.showOpenDialog(mainWindow, {
				title : data.title || '',
				properties: ['openDirectory']
			});
			break;
		case "openExternalUrl":
			if(data.type === 'exe'){
				execFile(data.path, [], (error, _stdout, stderr) => {
					if (error) {
					  console.error(`执行出错: ${error.message}`);
					  return;
					}
					if (stderr) {
					  console.error(`stderr: ${stderr}`);
					  return;
					}
				});
			}else if(data.type === 'url'){
				shell.openExternal(data.url)
			}
			break;
		default:
	}
	mainWindow.webContents.send("on-sys-api-message",{messageId,result});
});

